package com.lsl.strategy_pattern;


import com.lsl.strategy_pattern.dto.Character;
import com.lsl.strategy_pattern.service.AttackBehavior;
import com.lsl.strategy_pattern.service.SpeedBehavior;
import com.lsl.strategy_pattern.service.impl.attack.OrdinaryAttack;
import com.lsl.strategy_pattern.service.impl.attack.ReinforceAttack;
import com.lsl.strategy_pattern.service.impl.attack.SuperAttack;
import com.lsl.strategy_pattern.service.impl.speed.FastSpeed;
import com.lsl.strategy_pattern.service.impl.speed.NormalSpeed;
import com.lsl.strategy_pattern.service.impl.speed.SlowSpeed;


/**
 * 优点：
 * 1.策略模式从本质上说完成同一项工作但是完成方式不同 使用策略模式可以用相同的方式调用所有的算法 减少了算法之间耦合
 * 2.减少了if else这种逻辑判断
 * <p>
 * 缺点：
 * 1.增加很多策略类
 * 2.增加通讯开销 比如使用策略模式可能要带好几个参数 这些参数不一定对所有类都适用 这样就会造成没必要的通讯开销
 */


/**
 * 策略模式+简单工厂
 * <p>
 * <p>
 * 编写一个抽象类（Character）
 * 让所有的动物都继承这个类。速度和攻击方式是可以动态改变的。我们将需要动态改变的部分抽取出来。
 * 我们分别编写SpeedBehavior和AttackBehavior两个接口，将所有的速度和攻击行为都抽取出来。速度和攻击这里暂时写三种：
 *
 * @author liusl104
 */
public class AnimalStrategyFactoryContext {
    private final Character character;

    /**
     * 策略模式+简单工厂
     *
     * @param speed  传入的速度类型
     * @param attack 传入的攻击类型
     */
    public AnimalStrategyFactoryContext(String speed, String attack, Character character) {
        SpeedBehavior speedBehavior;
        switch (speed) {
            case "slow":
                speedBehavior = new SlowSpeed();
                break;
            case "normal":
                speedBehavior = new NormalSpeed();
                break;
            case "fast":
                speedBehavior = new FastSpeed();
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + speed);
        }
        AttackBehavior attackBehavior;
        switch (attack) {
            case "ordinary":
                attackBehavior = new OrdinaryAttack();
                break;
            case "normal":
                attackBehavior = new ReinforceAttack();
                break;
            case "super":
                attackBehavior = new SuperAttack();
                break;
            default:
                throw new IllegalStateException("Unexpected value: " + attack);
        }
        this.character = character;
        character.setAttackBehavior(attackBehavior);
        character.setSpeedBehavior(speedBehavior);
    }

    public void getBehavior() {
        character.attack();
        character.speed();
    }
}
